#include <stdio.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <stdlib.h>
#include <assert.h>
#include <string.h>
void task1()
{
    printf("Process task1\n");
}
void task2()
{
    printf("Process task2\n");
}
void task3()
{
    printf("Process task3\n");
}
typedef void (*func_t)();// 定义一个函数指针类型。
func_t Process_task[10];
void loadtask()
{
    memset(Process_task,0, sizeof(Process_task));
    Process_task[0]=task1;
    Process_task[1]=task2;
    Process_task[2]=task3;
}


int main()
{
    pid_t id = fork();
    assert(id!=-1);
    if(id==0)
    {
        // child process
        int cnt=5;
        while(cnt)
        {
            printf("child process running，pid:%d，ppid:%d，cnt:%d\n",getpid(),getppid(),cnt--);
            sleep(1);
        }
        exit(10);
    }
    loadtask();// 加载任务到函数指针数组里面。
    int status=0;
    while(1)
    {
        pid_t ret=waitpid(id,&status,WNOHANG);// WNOHANG是非阻塞等待，子进程没有退出，父进程检测一次之后，立即返回
        if(ret == 0) 
        {
            // waitpid调用成功，子进程没有退出
            printf("Wait for success，but the child process is still running\n");
            for(int i=0; Process_task[i]!=NULL; i++)
            {
                Process_task[i]();// 回调函数的方式，让父进程在轮询期间，做其他事情
            }
        }
        else if(ret == id)
        {
            // waitpid调用成功，子进程退出
            printf("wait success，exit code:%d，signal number:%d\n",(status>>8)&0xFF,status & 0x7F);
            break;
        }
        else 
        {
            // waitpid调用失败，例如等待了一个不属于该父进程的子进程
            printf("The waitpid call failed\n");
            break;
        }
        sleep(1);
    }








    //if(ret>0)
    //{
    //    // 是否正常退出
    //    if(WIFEXITED(status))
    //    {
    //        // 判断子进程退出码是什么
    //        printf("child process exit normally，exit code:%d\n",WEXITSTATUS(status));
    //    }
    //    else 
    //    {
    //        printf("child process don't exit normally\n");
    //    }
    //     // printf("wait success，exit code:%d，signal number:%d\n",(status>>8)&0xFF,status & 0x7F);
    //}
    return 0;
}
